﻿//基于逆波兰表示法，使用栈实现计算器功能(+/-/*//)
/*
逆波兰表达式又叫做后缀表达式。在通常的表达式中，二元运算符总是置于与之相关的两个运算对象之间，这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法，按此方法，每一运算符都置于其运算对象之后，故称为后缀表示。
a+b ---> a,b,+
a+(b-c) ---> a,b,c,-,+
a+(b-c)*d ---> a,b,c,-,d,*,+
a+d*(b-c)--->a,d,b,c,-,*,+
1、将一个中序表达式转化成为逆波兰表达式
构造两个栈S1，S2，S1用来存放表达式，S2用来暂时存放运算符，最后完成后，该栈是清空的。
（1）如果遇到的是数字，直接进栈S1
（2）如果遇到的是左括号，进栈S2
（3）如果遇到的是右括号，将S2中的运算符全部出栈压入S1中，注意括号不压入
（4）如果遇到的运算符
         1.如果此时栈S2为空，则直接将运算符加入到栈S2中；
         2.如果此时栈S2不为空，当前运算符的优先级大于等于栈顶运算符的优先级，那么直接入栈S2；
         3.如果此时栈S2不为空，当前运算符的优先级小于栈顶运算符的优先级，则将栈顶运算符一直出栈压入到栈S1中，  直到栈为空或者遇到一个运算符的优先级小于等于当前遍历的运算符的优先级，然后将该运算符压入到栈S2中。    
（5）遍历完整个中序表达式之后，如果栈S2中仍然存在运算符，那么将这些运算符依次出栈压入到栈S1中，直到栈为空。
2、利用逆波兰表达式求值
维护一个结果栈S3，该栈最后存放的是表达式的值。从左至右的遍历栈S1
（1）如果遇到的是数字，直接将数字压入到S3中
（2）如果遇到的是单目运算符，取S3栈顶的一个元素进行运算之后，将结果压入到栈S3中
（3）如果遇到的是双目运算符，取S3栈顶的两个元素，首先出栈的在左，后出栈的在右进行双目运算符的计算，将结果压入到S3中
遍历完整个栈S1，最后S3中的值就是逆波兰表达式的值。
*/